"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs_1 = __importDefault(require("fs"));
const geoserver_js_1 = require("./util/geoserver.js");
const about_js_1 = __importDefault(require("./about.js"));
class DatastoreClient {
    constructor(url, auth) {
        this.url = url;
        this.auth = auth;
    }
    async getDataStores(workspace) {
        return this.getStores(workspace, 'datastores');
    }
    async getCoverageStores(workspace) {
        return this.getStores(workspace, 'coveragestores');
    }
    async getWmsStores(workspace) {
        return this.getStores(workspace, 'wmsstores');
    }
    async getWmtsStores(workspace) {
        return this.getStores(workspace, 'wmtsstores');
    }
    async getStores(workspace, storeType) {
        const response = await fetch(this.url + 'workspaces/' + workspace + '/' + storeType + '.json', {
            credentials: 'include',
            method: 'GET',
            headers: {
                Authorization: this.auth
            }
        });
        if (!response.ok) {
            const geoServerResponse = await (0, geoserver_js_1.getGeoServerResponseText)(response);
            throw new geoserver_js_1.GeoServerResponseError(null, geoServerResponse);
        }
        return response.json();
    }
    async getDataStore(workspace, dataStore) {
        return this.getStore(workspace, dataStore, 'datastores');
    }
    async getCoverageStore(workspace, covStore) {
        return this.getStore(workspace, covStore, 'coveragestores');
    }
    async getWmsStore(workspace, wmsStore) {
        return this.getStore(workspace, wmsStore, 'wmsstores');
    }
    async getWmtsStore(workspace, wmtsStore) {
        return this.getStore(workspace, wmtsStore, 'wmtsstores');
    }
    async getStore(workspace, storeName, storeType) {
        const url = this.url + 'workspaces/' + workspace + '/' + storeType + '/' + storeName + '.json';
        const response = await fetch(url, {
            credentials: 'include',
            method: 'GET',
            headers: {
                Authorization: this.auth
            }
        });
        if (!response.ok) {
            const grc = new about_js_1.default(this.url, this.auth);
            if (await grc.exists()) {
                return;
            }
            else {
                const geoServerResponse = await (0, geoserver_js_1.getGeoServerResponseText)(response);
                throw new geoserver_js_1.GeoServerResponseError(null, geoServerResponse);
            }
        }
        return response.json();
    }
    async createGeotiffFromFile(workspace, coverageStore, layerName, layerTitle, filePath) {
        const stats = fs_1.default.statSync(filePath);
        const fileSizeInBytes = stats.size;
        const readStream = fs_1.default.createReadStream(filePath);
        return this.createGeotiffFromStream(workspace, coverageStore, layerName, layerTitle, readStream, fileSizeInBytes);
    }
    async createGeotiffFromStream(workspace, coverageStore, layerName, layerTitle, readStream, fileSizeInBytes) {
        const lyrTitle = layerTitle || layerName;
        let url = this.url + 'workspaces/' + workspace + '/coveragestores/' +
            coverageStore + '/file.geotiff';
        url += '?filename=' + lyrTitle + '&coverageName=' + layerName;
        const response = await fetch(url, {
            credentials: 'include',
            method: 'PUT',
            headers: {
                Authorization: this.auth,
                'content-type': 'image/tiff',
                'Content-length': fileSizeInBytes
            },
            body: readStream
        });
        if (!response.ok) {
            const geoServerResponse = await (0, geoserver_js_1.getGeoServerResponseText)(response);
            throw new geoserver_js_1.GeoServerResponseError(null, geoServerResponse);
        }
        return response.text();
    }
    async createPostgisStore(workspace, namespaceUri, dataStore, pgHost, pgPort, pgUser, pgPassword, pgSchema, pgDb, exposePk) {
        const body = {
            dataStore: {
                name: dataStore,
                type: 'PostGIS',
                enabled: true,
                workspace: {
                    name: workspace
                },
                connectionParameters: {
                    entry: [
                        {
                            '@key': 'dbtype',
                            $: 'postgis'
                        },
                        {
                            '@key': 'schema',
                            $: pgSchema
                        },
                        {
                            '@key': 'database',
                            $: pgDb
                        },
                        {
                            '@key': 'host',
                            $: pgHost
                        },
                        {
                            '@key': 'port',
                            $: pgPort
                        },
                        {
                            '@key': 'passwd',
                            $: pgPassword
                        },
                        {
                            '@key': 'namespace',
                            $: namespaceUri
                        },
                        {
                            '@key': 'user',
                            $: pgUser
                        },
                        {
                            '@key': 'Expose primary keys',
                            $: exposePk || false
                        }
                    ]
                }
            }
        };
        const url = this.url + 'workspaces/' + workspace + '/datastores';
        const response = await fetch(url, {
            credentials: 'include',
            method: 'POST',
            headers: {
                Authorization: this.auth,
                'content-type': 'application/json'
            },
            body: JSON.stringify(body)
        });
        if (!response.ok) {
            const geoServerResponse = await (0, geoserver_js_1.getGeoServerResponseText)(response);
            throw new geoserver_js_1.GeoServerResponseError(null, geoServerResponse);
        }
    }
    async createImageMosaicStore(workspace, coverageStore, zipArchivePath) {
        const readStream = fs_1.default.createReadStream(zipArchivePath);
        const url = this.url + 'workspaces/' + workspace + '/coveragestores/' + coverageStore + '/file.imagemosaic';
        const response = await fetch(url, {
            credentials: 'include',
            method: 'PUT',
            headers: {
                Authorization: this.auth,
                'content-type': 'application/zip'
            },
            body: readStream
        });
        if (!response.ok) {
            const geoServerResponse = await (0, geoserver_js_1.getGeoServerResponseText)(response);
            throw new geoserver_js_1.GeoServerResponseError(null, geoServerResponse);
        }
        return response.text();
    }
    ;
    async createWmsStore(workspace, dataStore, wmsCapabilitiesUrl) {
        const body = {
            wmsStore: {
                name: dataStore,
                type: 'WMS',
                capabilitiesURL: wmsCapabilitiesUrl
            }
        };
        const url = this.url + 'workspaces/' + workspace + '/wmsstores';
        const response = await fetch(url, {
            credentials: 'include',
            method: 'POST',
            headers: {
                Authorization: this.auth,
                'content-type': 'application/json'
            },
            body: JSON.stringify(body)
        });
        if (!response.ok) {
            const geoServerResponse = await (0, geoserver_js_1.getGeoServerResponseText)(response);
            throw new geoserver_js_1.GeoServerResponseError(null, geoServerResponse);
        }
    }
    async createWmtsStore(workspace, dataStore, wmtsCapabilitiesUrl) {
        const body = {
            wmtsStore: {
                name: dataStore,
                type: 'WMTS',
                capabilitiesURL: wmtsCapabilitiesUrl
            }
        };
        const url = this.url + 'workspaces/' + workspace + '/wmtsstores';
        const response = await fetch(url, {
            credentials: 'include',
            method: 'POST',
            headers: {
                Authorization: this.auth,
                'content-type': 'application/json'
            },
            body: JSON.stringify(body)
        });
        if (!response.ok) {
            const geoServerResponse = await (0, geoserver_js_1.getGeoServerResponseText)(response);
            throw new geoserver_js_1.GeoServerResponseError(null, geoServerResponse);
        }
    }
    async createWfsStore(workspace, dataStore, wfsCapabilitiesUrl, namespaceUrl, useHttpConnectionPooling) {
        const body = {
            dataStore: {
                name: dataStore,
                type: 'Web Feature Server (NG)',
                connectionParameters: {
                    entry: [
                        {
                            '@key': 'WFSDataStoreFactory:GET_CAPABILITIES_URL',
                            $: wfsCapabilitiesUrl
                        },
                        {
                            '@key': 'namespace',
                            $: namespaceUrl
                        },
                        {
                            '@key': 'WFSDataStoreFactory:USE_HTTP_CONNECTION_POOLING',
                            $: useHttpConnectionPooling !== false ? 'true' : 'false'
                        }
                    ]
                }
            }
        };
        const url = this.url + 'workspaces/' + workspace + '/datastores';
        const response = await fetch(url, {
            credentials: 'include',
            method: 'POST',
            headers: {
                Authorization: this.auth,
                'content-type': 'application/json'
            },
            body: JSON.stringify(body)
        });
        if (!response.ok) {
            const geoServerResponse = await (0, geoserver_js_1.getGeoServerResponseText)(response);
            throw new geoserver_js_1.GeoServerResponseError(null, geoServerResponse);
        }
    }
    async deleteDataStore(workspace, dataStore, recurse) {
        let url = this.url + 'workspaces/' + workspace + '/datastores/' + dataStore;
        url += '?recurse=' + recurse;
        const response = await fetch(url, {
            credentials: 'include',
            method: 'DELETE',
            headers: {
                Authorization: this.auth
            }
        });
        if (!response.ok) {
            const geoServerResponse = await (0, geoserver_js_1.getGeoServerResponseText)(response);
            throw new geoserver_js_1.GeoServerResponseError(null, geoServerResponse);
        }
    }
    async deleteCoverageStore(workspace, coverageStore, recurse) {
        let url = this.url + 'workspaces/' + workspace + '/coveragestores/' + coverageStore;
        url += '?recurse=' + recurse;
        const response = await fetch(url, {
            credentials: 'include',
            method: 'DELETE',
            headers: {
                Authorization: this.auth
            }
        });
        if (!response.ok) {
            const geoServerResponse = await (0, geoserver_js_1.getGeoServerResponseText)(response);
            switch (response.status) {
                case 401:
                    throw new geoserver_js_1.GeoServerResponseError('Deletion failed. There might be dependant objects to ' +
                        'this store. Delete them first or call this with "recurse=false"', geoServerResponse);
                default:
                    throw new geoserver_js_1.GeoServerResponseError(null, geoServerResponse);
            }
        }
    }
    async createGpkgStore(workspace, dataStore, gpkgPath) {
        const body = {
            dataStore: {
                name: dataStore,
                type: 'GeoPackage',
                connectionParameters: {
                    entry: [
                        {
                            '@key': 'database',
                            $: `file:${gpkgPath}`
                        },
                        {
                            '@key': 'dbtype',
                            $: 'geopkg'
                        }
                    ]
                }
            }
        };
        const url = this.url + 'workspaces/' + workspace + '/datastores';
        const response = await fetch(url, {
            credentials: 'include',
            method: 'POST',
            headers: {
                Authorization: this.auth,
                'content-type': 'application/json'
            },
            body: JSON.stringify(body)
        });
        if (!response.ok) {
            const geoServerResponse = await (0, geoserver_js_1.getGeoServerResponseText)(response);
            throw new geoserver_js_1.GeoServerResponseError(null, geoServerResponse);
        }
    }
}
exports.default = DatastoreClient;
